package com.hxc.sercurity.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hxc.sercurity.configu.projo.JwtUtil;
import com.hxc.sercurity.configu.projo.LoginUserDetails;
import com.hxc.sercurity.configu.projo.User;
import io.netty.util.internal.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author 韩先楚
 */
@Service
@Slf4j
public class LoginServiceImpl {

    @Autowired
    private StringRedisTemplate redis;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;


    public String getUser(User user) {
        //由于将登入接口放行了,所以调用认证过滤器链来认证
        //调用 AuthenticationManager 的 authenticate 方法进行认证
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
        //将封装了用户名和密码的Authentication对象最后传递给UserDetailService的loadUserByUsername方法来进行认证
        Authentication authenticate = authenticationManager.authenticate(auth);
        //判断是否认证成功
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("用户名或密码错误");
        }
        String jwt = null;
        //得到实现了UserDetail接口的自定义实现类
        UserDetails userDetails = userDetailsService.loadUserByUsername(user.getUsername());
        if (userDetails instanceof LoginUserDetails) {
            LoginUserDetails loginUserDetails = (LoginUserDetails) userDetails;
            // 使用 loginUserDetails 对象
            User user1 = loginUserDetails.getUser();
            //获取userid
            Integer userId = user1.getId();
            //生成Jwt令牌
            JwtUtil hxc = new JwtUtil("hxc");
            Map<String, Object> map = new HashMap();
            map.put("userId", userId);
            jwt = hxc.generateToken(map, 60 * 60 * 24 * 1000L);
            ObjectMapper mapper = new ObjectMapper();
            //将用户信息存入redis中
            try {
                redis.opsForHash().put("loginUser", "user" + userId, mapper.writeValueAsString(user1));

            } catch (JsonProcessingException e) {
                log.info("存入redis失败");
                throw new RuntimeException(e);
            }

        }
        return jwt;
    }

    /**
     * 退出登录
     *
     * @return
     */
    public String Loginout() {
        //获取SecurityContextHolder中的Authentication对象
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取用户id
        if (authentication != null) {
            // 获取LoginUserDetails对象
            User userDetails = (User)authentication.getPrincipal();

            // 检查LoginUserDetails对象是否为null
            if (userDetails != null) {
                // 获取用户ID
                Integer id = userDetails.getId();
                //从Redis中删除用户信息
                if ( redis.opsForHash().hasKey("loginUser", "user" + id) )
                {
                    redis.opsForHash().delete("loginUser", "user" + id);
                }
                else
                {
                    log.info("redis中没有该用户信息");
                    return "redis中没有该用户信息";
                }
            }
        }
        else
            log.info("没有用户信息");

        return "成功删除该用户在Redis中的信息";
    }
}

